package command;

import command.CommandConstants.CommandType;

/**
 * An action in the game, for example moving a creature to another tile.
 * Implements Serializable so that it can be transmitted via XML-RPC
 * @author Oscar
 *
 *
 */

public class Command{
	
	CommandType commandType;
	
	/**
	 * The source of the Command, ie. the card that moves or activates an ability
	 */
	int actingCardId;
	
	
	/**
	 * Used if the commandType requires a target tile.
	 */
	int targetTileId;
	/**
	 * Used if the commandType requires a target card.
	 */
	int targetCardId;
	
	/**
	 * Used if the commandType requires a target player.
	 */
	int targetPlayerId;
	
	/**
	 * Id of the player who issued the command.
	 */
	int sourcePlayerId;
	
	/**
	 * The effect that is to be executed.
	 */
	int effectId;
	
	public Command(){
		
	}
	
	/**
	 * 
	 * @param commandType
	 * @param actingCardId
	 * @param effectId
	 * @param targetTileId
	 * @param targetCardId
	 * @param targetPlayerId
	 * @param sourcePlayerId
	 */
	public Command(CommandType commandType, int actingCardId, int effectId, int targetTileId, int targetCardId, int targetPlayerId, int sourcePlayerId){
		this.commandType=commandType;
		this.actingCardId=actingCardId;
		this.effectId = effectId;
		this.targetTileId=targetTileId;
		this.targetCardId=targetCardId;
		this.targetPlayerId=targetPlayerId;
		this.sourcePlayerId=sourcePlayerId;
	}
	
	public int getActingCardId(){
		return actingCardId;
	}
	public int getSourcePlayerId(){
		return sourcePlayerId;
	}
	public int getEffectId(){
		return effectId;
	}
	public int getTargetTileId(){
		return targetTileId;	
	}
	public int getTargetCardId(){
		return targetCardId;
	}
	public int getTargetPlayerId(){
		return targetPlayerId;
	}
	public CommandType getCommandType(){
		return commandType;
	}


	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + actingCardId;
		result = prime * result
				+ ((commandType == null) ? 0 : commandType.hashCode());
		result = prime * result + effectId;
		result = prime * result + sourcePlayerId;
		result = prime * result + targetCardId;
		result = prime * result + targetPlayerId;
		result = prime * result + targetTileId;
		return result;
	}


	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Command other = (Command) obj;
		if (actingCardId != other.actingCardId)
			return false;
		if (commandType == null) {
			if (other.commandType != null)
				return false;
		} else if (!commandType.equals(other.commandType))
			return false;
		if (effectId != other.effectId)
			return false;
		if (sourcePlayerId != other.sourcePlayerId)
			return false;
		if (targetCardId != other.targetCardId)
			return false;
		if (targetPlayerId != other.targetPlayerId)
			return false;
		if (targetTileId != other.targetTileId)
			return false;
		return true;
	}
	
	public String toString(){
		return commandType + ":" + actingCardId + ":" + effectId + ":" +targetTileId + ":" + targetCardId + ":" + targetPlayerId + ":" + sourcePlayerId;
	}
	
	/**
	 * Generates a Command that is identical to fromString(toString(CommandObject))
	 * @param s
	 * @return
	 */
	public static Command fromString(String s){
		String[] sr = s.split(":");
		if(sr[0].equals("move"))
			return new Command(CommandType.move ,Integer.parseInt(sr[1]), Integer.parseInt(sr[2]), Integer.parseInt(sr[3]), Integer.parseInt(sr[4]), Integer.parseInt(sr[5]), Integer.parseInt(sr[6]));
		else if (sr[0].equals("attack"))
			return new Command(CommandType.attack ,Integer.parseInt(sr[1]), Integer.parseInt(sr[2]), Integer.parseInt(sr[3]), Integer.parseInt(sr[4]), Integer.parseInt(sr[5]), Integer.parseInt(sr[6]));
		else if (sr[0].equals("activateAbility"))
			return new Command(CommandType.activateAbility ,Integer.parseInt(sr[1]), Integer.parseInt(sr[2]), Integer.parseInt(sr[3]), Integer.parseInt(sr[4]), Integer.parseInt(sr[5]), Integer.parseInt(sr[6]));
		else if (sr[0].equals("playCard"))
			return new Command(CommandType.playCard ,Integer.parseInt(sr[1]), Integer.parseInt(sr[2]), Integer.parseInt(sr[3]), Integer.parseInt(sr[4]), Integer.parseInt(sr[5]), Integer.parseInt(sr[6]));
		else if (sr[0].equals("discardCard"))
			return new Command(CommandType.discardCard ,Integer.parseInt(sr[1]), Integer.parseInt(sr[2]), Integer.parseInt(sr[3]), Integer.parseInt(sr[4]), Integer.parseInt(sr[5]), Integer.parseInt(sr[6]));
		else if (sr[0].equals("claimTile"))
			return new Command(CommandType.claimTile ,Integer.parseInt(sr[1]), Integer.parseInt(sr[2]), Integer.parseInt(sr[3]), Integer.parseInt(sr[4]), Integer.parseInt(sr[5]), Integer.parseInt(sr[6]));
		else if (sr[0].equals("endTurn"))
			return new Command(CommandType.endTurn ,Integer.parseInt(sr[1]), Integer.parseInt(sr[2]), Integer.parseInt(sr[3]), Integer.parseInt(sr[4]), Integer.parseInt(sr[5]), Integer.parseInt(sr[6]));
		else if (sr[0].equals("battleTarget"))
			return new Command(CommandType.battleTarget ,Integer.parseInt(sr[1]), Integer.parseInt(sr[2]), Integer.parseInt(sr[3]), Integer.parseInt(sr[4]), Integer.parseInt(sr[5]), Integer.parseInt(sr[6]));
		else if (sr[0].equals("battleStart"))
			return new Command(CommandType.battleStart ,Integer.parseInt(sr[1]), Integer.parseInt(sr[2]), Integer.parseInt(sr[3]), Integer.parseInt(sr[4]), Integer.parseInt(sr[5]), Integer.parseInt(sr[6]));
		else{
			return null;
		}
			
	}


}
